/*!
 * avangard/interface_controller.js
 * © 2009 avangardonline.ru
 * @author BlooDHounD <http://www.controller.by>
 */

if ( !window.controller ) throw new Error( '"controller" not initialized' );

controller.require( 'avangard' );

if ( !avangard.InterfaceController ) {

	controller.require( 'controller.events.EventDispatcher' );
	controller.require( 'controller.utils' );
	controller.require( 'controller.template' );

	/**
	 * класс работы с чатом
	 * @class
	 * @namespace	avangard.community
	 * @extends		controller.events.EventDispatcher
	 * @author		BlooDHounD	<http://www.controller.by>
	 */
	avangard.InterfaceController = function() {

		//--------------------------------------------------------------------------
		//
		//  Class variables
		//
		//--------------------------------------------------------------------------

		/**
		 * @private
		 */
		var	$ =			controller,
			template =	$.template,
			utils =		$.utils,

			doc =		window.document,

			_logging =	$.isLogging(),

			tpl_wait =	template.loadTemplate( '/tpl/wait.tpl' ),
			tpl_retry =	template.loadTemplate( '/tpl/retry.tpl' );

		//--------------------------------------------------------------------------
		//
		//  Constructor
		//
		//--------------------------------------------------------------------------

		/**
		 * @constructor
		 */
		var InterfaceController = function(contentID, templateID, uri) {
			InterfaceController.superPrototype.constructor.call( this );

			this._tpl_content =	template.getTemplate( templateID );
			this.display =		doc.getElementById( contentID );

			if ( uri ) {
				this._uri = uri;
				this.update();
			} else {
				this.display.innerHTML = this._tpl_content();
				utils.deferredCall(
					this,
					function() {
						if ( this.onData ) this.onData();
					}
				);
			}

		};

		$.extend( InterfaceController, $.events.EventDispatcher );

		var InterfaceControllerPrototype = InterfaceController.prototype;

		//--------------------------------------------------------------------------
		//
		//  Variables
		//
		//--------------------------------------------------------------------------

		/**
		 * @private
		 * @type	{String}
		 */
		InterfaceControllerPrototype._uri = null;

		/**
		 * @private
		 * @type	{HTMLElement}
		 */
		InterfaceControllerPrototype._tpl_content = null;

		//--------------------------------------------------------------------------
		//
		//  Properties
		//
		//--------------------------------------------------------------------------

		/**
		 * @private
		 * @type	{HTMLElement}
		 */
		InterfaceControllerPrototype.display = null;

		/**
		 * @private
		 * @type	{Function}
		 */
		InterfaceControllerPrototype.onData = null;

		//--------------------------------------------------------------------------
		//
		//  Event handlers
		//
		//--------------------------------------------------------------------------

		/**
		 * @private
		 * @this	{CommunityController}
		 * @param	{String}	data
		 */
 		var onDataLoader = function(data) {
			try {

				$.require( 'controller.utils.crypto.json' );
				var o = ( data ? utils.crypto.json.deserialize( data ) : { error: { message: 'empty string' } } );
				if ( 'error' in o ) {
					throw new Error( o.error.message );
				} else {

					this.display.innerHTML = this._tpl_content( o );
					if ( this.onData ) this.onData( o );

				}

			} catch ( e ) {

				onFailLoader.call( this, e.message + ( e.stack ? '\n' + e.stack : '' ) );

			}
		};

		/**
		 * @private
		 * @this	{CommunityController}
		 * @param	{String}	message
		 */
		var onFailLoader = function(message) {
			var id = $.createUniqID();
			this.display.innerHTML = tpl_retry(
				( _logging ? message : 'Извините, произошла ошибка.' ),
				id,
				'Повторить попытку'
			);
			$.require( 'controller.events.dom' );
			$.events.dom.addEventListener(
				doc.getElementById( id ),
				'submit',
				utils.createDelegate( this, this.update )
			);
		};

		//--------------------------------------------------------------------------
		//
		//  Methods
		//
		//--------------------------------------------------------------------------

		/**
		 * @method
		 */
		InterfaceControllerPrototype.update = function() {
			this.display.innerHTML = tpl_wait();
			this.request();
		};

		/**
		 * @method
		 */
		InterfaceControllerPrototype.request = function() {
			$.require( 'controller.Flash.dataLoader' );
			var responder = $.Flash.dataLoader.load( this._uri );
			responder.onData = utils.createDelegate( this, onDataLoader );
			responder.onFail = utils.createDelegate( this, onFailLoader );
		};

		/**
		 * @method
		 * @override
		 * @return	{String}
		 */
		InterfaceControllerPrototype.toString = function() {
			return '[InterfaceController object]';
		};

		//--------------------------------------------------------------------------
		//
		//  Class methods
		//
		//--------------------------------------------------------------------------

		/**
		 * @static
		 * @method
		 * @override
		 * @return	{String}
		 */
		InterfaceController.toString = function() {
			return '[class InterfaceController]';
		};

		return InterfaceController;

	}();

}